#ifndef OBJECTFACTORY_H_
#define OBJECTFACTORY_H_

#include <map>
using std::map;




template< typename ClassIDType, typename BaseClassType>
class ObjectFactory
{
private:
	typedef BaseClassType* (*CreatedObjects)( void );

	map<ClassIDType,CreatedObjects> m_ObjectsCreation;

	static ObjectFactory<ClassIDType,BaseClassType> Obj_Instance;

	ObjectFactory( void ){}
	ObjectFactory( const ObjectFactory& );
	ObjectFactory& operator=( const ObjectFactory& );
	~ObjectFactory( void ){}

	template<typename DerivedClassType>
	static BaseClassType* ConstructObject( void )
	{
		return new DerivedClassType;
	}
public:
	static ObjectFactory<ClassIDType,BaseClassType>* GetInstance( void )
	{
		return &Obj_Instance;
	}

	template< typename DerivedClassType>
	bool RegisterClassType( ClassIDType id )
	{
		std::pair<ClassIDType,CreatedObjects> ObjType;

		ObjType.first = id;
		ObjType.second = ConstructObject<DerivedClassType>;

		m_ObjectsCreation.insert( ObjType );

		return true;
	}
	bool	UnregisterClassType( ClassIDType ID )
	{
		map<ClassIDType,CreatedObjects>::iterator iter = m_ObjectsCreation.find( ID );

		if( iter == m_ObjectsCreation.end() )
			return false;

		m_ObjectsCreation.erase( iter );

		return true;
	}
	BaseClassType* CreateObject( ClassIDType ID)
	{
		map<ClassIDType,CreatedObjects>::iterator iter = m_ObjectsCreation.find( ID );

		if( iter == m_ObjectsCreation.end() )
			return NULL;

		return (*iter).second() ;

	}
	void ShutdownObjectFactory( void )
	{
		m_ObjectsCreation.clear();
	}

};
template<typename ClassIDType, typename BaseClassType>
ObjectFactory<ClassIDType,BaseClassType>
ObjectFactory<ClassIDType,BaseClassType>::Obj_Instance;

#endif 